package com.ruoyi.web.controller.tool;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ChatClient {

    private final String host;
    private final int port;
    private ChannelHandlerContext ctx;
    private ScheduledExecutorService executorService;

    public ChatClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try (Scanner scanner = new Scanner(System.in)) {
            String nickname;
            System.out.print("输入您的昵称: ");
            nickname = scanner.nextLine();
            //创建自定义线程池，使用单个线程
            executorService = new ScheduledThreadPoolExecutor(1);

            Bootstrap b = new Bootstrap();
            b.group(workerGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(new ChatClientHandler(nickname));
                        }
                    });

            ChannelFuture f = b.connect(host, port).sync();

            // Start reading user input in a scheduled task
            executorService.scheduleAtFixedRate(() -> readUserInput(scanner), 0L, 100L, TimeUnit.MILLISECONDS);

            // Wait until the connection is closed.
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            if (executorService != null) {
                executorService.shutdownNow();
            }
        }
    }

    private void readUserInput(Scanner scanner) {
        if (!scanner.hasNextLine()) {return;}

        try {
            System.out.print("> ");
            String line = scanner.nextLine();

            if (line.startsWith("/msg ")) {
                String[] parts = line.split(" ", 3);
                if (parts.length == 3 && !parts[1].isEmpty()) {
                    ctx.channel().writeAndFlush(line + "\r\n");
                } else {
                    System.out.println("无效的私聊消息格式。请使用 '/msg [昵称] [消息]'");
                }
            } else {
                // 处理公共聊天或其他命令...
                ctx.channel().writeAndFlush(line + "\r\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 如果出现异常，可以考虑停止读取任务并关闭连接
            executorService.shutdownNow();
            ctx.close();
        }
    }

    public class ChatClientHandler extends ChannelInboundHandlerAdapter {

        private final String nickname;

        public ChatClientHandler(String nickname) {
            this.nickname = nickname;
        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            System.out.println("已连接服务器.");
            ChatClient.this.ctx = ctx;
            ctx.writeAndFlush("/nick " + nickname + "\r\n");
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            String message = (String) msg;
            // 输出接收到的消息到控制台或其他UI组件
            System.out.println(message);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }

    public static void main(String[] args) throws Exception {
        ChatClient client = new ChatClient("localhost", 8080);
        client.start();
    }
}
